#include <iostream>
#include <string>
using namespace std;
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>

#include <assert.h>
#include <cstring>

// int main()
// {
//     // 创建匿名管道
//     int pipefd[2] = {0};
//     int n = pipe(pipefd);
//     assert(n == 0); // 确定返回值为0，打开了文件，否则就是打开失败
//     (void)n;        // 这里是为了防止警告未使用的变量n

//     // 创建子进程
//     pid_t id = fork();
//     assert(id != -1); // 保证子进程一定创建成功
//     if (id == 0)      // 子进程
//     {
//         // 读，关闭写端1
//         close(pipefd[1]);
//         // cout << "子进程关闭写端" << endl;
//         // cout << "子进程关闭读端" << endl;
//         close(pipefd[0]);
//         // 子进程开始读取数据
//         // char buff[1024 * 8];
//         // while (true)
//         // {
//         //     sleep(5);
//         //     // ssize_t 就是long int
//         //     ssize_t s = read(pipefd[0], buff, sizeof(buff) - 1);
//         //     if (s > 0)
//         //     {
//         //         // 把读取到的字符串最后一个位置手动改为\0
//         //         buff[s] = 0;
//         //         cout << "子进程:: "<< getpid() << "接收到信息::" << buff << endl;
//         //         //cout << "child get a message[" << getpid() << "] Father# " << buff << endl;
//         //     }
//         //     else if(s == 0)
//         //     {
//         //         cout << "father quite, me quite" << endl;
//         //         break;
//         //     }
//         // }

//         exit(0); // 子进程退出，会自动关闭子进程的文件描述符并清空缓冲区
//     }

//     // 父进程写入，关闭读端0
//     close(pipefd[0]);
//     string str = "我是父进程，我正在给子进程发消息";
//     int count = 0; //  计数
//     char send_buff[1024];
//     while (true)
//     {
//         // 用字符流插入到send_buff中
//         snprintf(send_buff, sizeof(send_buff), "%s[%d]:%d", str.c_str(), getpid(), count++);
//         write(pipefd[1], send_buff, strlen(send_buff)); // 这里不能用sizeof，不然会多写内容
//         cout << "count::" << count << endl;
//         // sleep(1);
//         // if(count == 5)
//         // {
//         //     cout << "writer quite" << endl;
//         //     break;
//         // }
//     }

//     // 通信结束，关闭父进程文件描述符1
//     close(pipefd[1]);

//     // 等待子进程退出
//     pid_t ret = waitpid(id, nullptr, 0);
//     cout << "id::" << id << "   ret::" << ret << endl;
//     assert(ret > 0); // 确保成功等待子进程
//     (void)ret; // 与上方n同理

//     return 0;
// }


int main()
{
    // 创建匿名管道
    int pipefd[2] = {0};
    int n = pipe(pipefd);
    assert(n == 0); // 确定返回值为0，打开了文件，否则就是打开失败
    (void)n;        // 这里是为了防止警告未使用的变量n

    // 创建子进程
    pid_t id = fork();
    assert(id != -1); // 保证子进程一定创建成功
    if (id == 0)      // 子进程
    {
        // 读，关闭写端1
        close(pipefd[1]);
        while(1);// 子进程保持啥也不干，不退出就行

        exit(0); // 子进程退出，会自动关闭子进程的文件描述符并清空缓冲区
    }

    // 父进程写入，关闭读端0
    close(pipefd[0]);
    string str = "我是父进程，我正在给子进程发消息";
    int count = 1;
    while (true)
    {
        char c;
        // 用字符流插入到send_buff中
        write(pipefd[1], &c, 1); // 这里不能用sizeof，不然会多写内容
        cout << "count::" << count++ << endl;
    }

    // 通信结束，关闭父进程文件描述符1
    close(pipefd[1]);

    // 等待子进程退出
    pid_t ret = waitpid(id, nullptr, 0);
    cout << "id::" << id << "   ret::" << ret << endl;
    assert(ret > 0); // 确保成功等待子进程
    (void)ret; // 与上方n同理

    return 0;
}
